package com.dkh.recommend.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.dkh.recommend.dto.LoginFormDTO;
import com.dkh.recommend.dto.PasswordDTO;
import com.dkh.recommend.dto.Result;
import com.dkh.recommend.dto.UserDTO;
import com.dkh.recommend.entity.TbUser;
import com.dkh.recommend.mapper.TbUserMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dkh.recommend.service.ITbUserService;
import com.dkh.recommend.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.dkh.recommend.utils.RedisConstants.LOGIN_USER_KEY;
import static com.dkh.recommend.utils.RedisConstants.LOGIN_USER_TTL;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author dkh
 * @since 2022-12-14
 */
@Slf4j
@Service
@Transactional
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser> implements ITbUserService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 登录功能
     * @param loginform
     * @return
     */
    @Override
    public Result login(LoginFormDTO loginform) {

//        账号
        String userNumber = loginform.getUserNumber();
//        密码
        String userPassword = loginform.getUserPassword();

        if (userNumber == null || userNumber.equals("")|| userPassword== null || userPassword.equals("")  ){
//            用户账号或密码为空，返回错误信息
            return Result.fail("账号或密码为空");
        }
//        根据账号或密码查询用户 select * from tb_user where user_number = ? && user_password = ?
        LambdaQueryWrapper<TbUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TbUser::getUserNumber,userNumber);
        queryWrapper.eq(TbUser::getUserPassword,userPassword);
        TbUser user = getOne(queryWrapper);

        if (user == null || user.equals("")){
            return Result.fail("账号或密码错误");
        }

//        将user转为userDTO传输模式传给前端
        UserDTO userDTO = BeanUtil.toBean(user, UserDTO.class);

        // 6.存在，保存用户信息到 ThreadLocal
//        UserHolder.saveUser(userDTO);
//        转成token存入redis....
//        todo 转成token存入redis....
        // 7.1.随机生成token，作为登录令牌
        String token = UUID.randomUUID().toString(true);
        // 7.2.将User对象转为HashMap存储
        Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, new HashMap<>(),
                CopyOptions.create()
                        .setIgnoreNullValue(true)
                        .setFieldValueEditor((filedName, fieldValue)-> fieldValue.toString()));
        // 7.3.存储
        String tokenKey =  LOGIN_USER_KEY + token;
        stringRedisTemplate.opsForHash().putAll(tokenKey,userMap);
        // 7.4.设置token有效期
        stringRedisTemplate.expire(tokenKey, LOGIN_USER_TTL, TimeUnit.DAYS);
        // 8.返回token
        return Result.ok(token);
    }

    /**
     * 用户注册功能
     * @param tbUser
     * @return
     */
    @Override
    public Result register(TbUser tbUser) {
//        如果账号密码为空则失败！！
        if (tbUser.getUserNumber() == null || tbUser.getUserNumber().equals("") || tbUser.getUserPassword() == null || tbUser.getUserPassword().equals("")){
            return Result.fail("账号密码不能为空！");
        }

//        判断是否usernumber存在
        LambdaQueryWrapper<TbUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(TbUser::getUserNumber,tbUser.getUserNumber());
        List<TbUser> list = list(userWrapper);
//
        if (list.size() > 0)
        {
//          不为空，usernumber已经存在
            return Result.fail("账号："+tbUser.getUserNumber()+"已经存在");
        }

        boolean save1 = save(tbUser);
        if (save1){
        return Result.ok();
        }else {
            return Result.fail("注册失败，请重试！");
        }

    }

    /**
     * 修改用户信息
     * @param tbUser
     * @return
     */
    @Override
    public Result updateUser(TbUser tbUser) {

        boolean b = updateById(tbUser);
        if (!b){
            return Result.fail("修改用户信息失败");
        }

        return Result.ok(tbUser);
    }

//    根据用户id获取用户信息
    @Override
    public Result getUserById(String id) {
        LambdaQueryWrapper<TbUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TbUser::getUserId,id);
        TbUser user = getOne(queryWrapper);
        UserDTO userDTO = BeanUtil.toBean(user, UserDTO.class);
        return Result.ok(userDTO);
    }

//    获取当前登录用户的信息
    @Override
    public Result getMyAllInfoById2() {
        Long userId = UserHolder.getUser().getUserId();
        LambdaQueryWrapper<TbUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TbUser::getUserId,userId);
        TbUser user = getOne(queryWrapper);
        return Result.ok(user);
    }

    @Override
    public Result UpdatePassword(PasswordDTO passwordDTO) {
        Long userId = UserHolder.getUser().getUserId();
        if (passwordDTO.getOldPassword().isEmpty()||passwordDTO.getNewPassword().isEmpty()){
            return Result.fail("请输入密码");
        }
        LambdaUpdateWrapper<TbUser> warpper = new LambdaUpdateWrapper<>();
        warpper.eq(TbUser::getUserId,userId);
        warpper.eq(TbUser::getUserPassword,passwordDTO.getOldPassword());
        warpper.set(TbUser::getUserPassword,passwordDTO.getNewPassword());
        boolean b = update(warpper);
        if (!b){
            return Result.fail("请输入正确当前密码");
        }
        return Result.ok();
    }


    /**
     * 退出登录
     * @param token
     * @return
     */
    @Override
    public Result OutLogin(String token) {

//        删除登录令牌
        String tokenKey =  LOGIN_USER_KEY + token;
        stringRedisTemplate.delete(tokenKey);
        return Result.ok();
    }


}
